package controllers

import (
	"Squid/common/random"
	"Squid/common/request"
	"Squid/common/responses"
	"Squid/enum/code"
	"Squid/enum/fileds"
	"Squid/models"
	"Squid/modules/crontab/common"
	"Squid/repositories"
	"github.com/labstack/echo/v4"
	"net/http"
	"time"
)

type JobController struct {
	repository *repositories.JobManager
}

func NewJobController() (jobController *JobController, err error) {
	var (
		jobManager *repositories.JobManager
	)

	if jobManager, err = repositories.NewJobManager(); err != nil {
		return &JobController{}, err
	}
	return &JobController{
		repository: jobManager,
	}, err
}

func (controller *JobController)SaveJob(c echo.Context) error {
	var (
		v          *models.Job
		err        error
		id         string
	)

	v = new(models.Job)
	if err = c.Bind(v); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "绑定参数失败", err.Error()))
	}

	if v.Name == "" {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "job名不能为空", ""))
	}
	if v.Command == "" {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "command不能为空", ""))
	}
	if v.CronExpr == "" {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "表达式不能为空", ""))
	}

	//TODO 解析表达式是否报错

	v.ID = random.RandDateAndString(17)
	v.Status = fileds.Enable
	v.UpdateAt = time.Now().Format("2006-01-02 15:04:05")
	v.CreateAt = time.Now().Format("2006-01-02 15:04:05")
	v.IsDelete = fileds.Enable


	if id, err = controller.repository.InsertJob(v); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.QueryError, "插入有误", err.Error()))
	}

	return c.JSON(http.StatusOK, responses.Response(200, "成功", id))
}

func (controller *JobController)GetJob(c echo.Context) error {
	var (
		id         string
		err        error
		job        *models.Job
	)

	id = c.Param("id")
	if id == "" {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "id不能为空", ""))
	}
	if job, err = controller.repository.SelectJobById(id); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.QueryError, err.Error(), ""))
	}
	return c.JSON(http.StatusOK, responses.Response(200, "成功", job))
}

func (controller *JobController)UpdateJob(c echo.Context) error {
	var (
		id         string
		s          *models.Job
		err        error
		job        *models.Job
	)

	id = c.Param("id")
	if id == "" {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "id不能为空", ""))
	}
	s = new(models.Job)
	if err = c.Bind(s); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "绑定参数失败", err.Error()))
	}

	if job, err = controller.repository.UpdateUserById(id, s); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.ServerError, "更新失败", err.Error()))
	}

	return c.JSON(http.StatusOK, responses.Response(200, "成功", job))
}

func (controller *JobController)DeleteJob(c echo.Context) error {
	var (
		id         string
		err        error
		boole      bool
	)
	id = c.Param("id")
	if id == "" {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "id不能为空", ""))
	}


	if boole, err = controller.repository.DeleteJobById(id); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.ServerError, "删除失败", err.Error()))
	}

	return c.JSON(http.StatusOK, responses.Response(200, "成功", boole))
}

func (controller *JobController)GetJobs(c echo.Context) error {
	var (
		s          *request.Job
		results    responses.Results
		err        error
	)

	s = new(request.Job)
	//if err = (&echo.DefaultBinder{}).BindPathParams(c, &s); err != nil {
	//	return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "绑定参数失败", err))
	//}
	if err = echo.QueryParamsBinder(c).Int("size", &s.Size).Int("page", &s.Page).String("name", &s.Name).String("sort", &s.Sort).String("sort_filed", &s.SortFiled).BindError(); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "绑定参数失败", err))
	}
	if s.Page == 0 {
		s.Page = 1
	}
	if s.Size == 0 {
		s.Size = 10
	}
	if !request.ValidateSort(s.Sort) {
		s.Sort = fileds.ASC
	}
	if !request.ValidateJobSortFile(s.SortFiled) {
		s.SortFiled = fileds.CREATEAt
	}


	if results, err = controller.repository.SelectJobs(s); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.QueryError, "sql错误", err.Error()))
	}

	return c.JSON(http.StatusOK, responses.Response(200, "成功", results))
}

func (controller *JobController)SyncJobEtcd(c echo.Context) error {
	var (
		err        error
		v          *models.Job
		oldJob     *common.Job
	)

	v = new(models.Job)
	if err = c.Bind(v); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "绑定参数失败", err.Error()))
	}
	if v.ID == "" {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "id不能为空", ""))
	}

	if oldJob, err = controller.repository.SyncJobToEtcd(v.ID); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.ServerError, "失败", err.Error()))
	} else {
		return c.JSON(http.StatusOK, responses.Response(200, "成功", oldJob))
	}
}

func (controller *JobController)DeleteJobEtcd(c echo.Context) error {
	var (
		id         string
		oldJob     *common.Job
		err error
	)

	id = c.Param("id")
	if id == "" {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "id不能为空", ""))
	}


	if oldJob, err = controller.repository.DeleteJobFromEtcd(id); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.QueryError, "失败", err.Error()))
	} else {
		return c.JSON(http.StatusOK, responses.Response(200, "成功", oldJob))
	}
}

func (controller *JobController)GetEtcdJobs(c echo.Context) error {
	var (
		jobList []*common.Job
		err error
	)

	if jobList, err = controller.repository.SelectEtcdJobs(); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.QueryError, "失败", err.Error()))
	} else {
		return c.JSON(http.StatusOK, responses.Response(200, "成功", jobList))
	}
}

func (controller *JobController)KillJobEtcd(c echo.Context) error {
	var (
		v *models.Job
		err error
	)

	v = new(models.Job)
	if err = c.Bind(v); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "绑定参数失败", err.Error()))
	}
	if v.ID == "" {
		return c.JSON(http.StatusOK, responses.Response(code.ParameterError, "id不能为空", ""))
	}

	if err = controller.repository.KillEtcdJobById(v.ID); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.QueryError, "失败", err.Error()))
	} else {
		return c.JSON(http.StatusOK, responses.Response(200, "成功", ""))
	}
}

func (controller *JobController)GetWorkers(c echo.Context) error {
	var (
		workerArr []string
		err error
	)

	if workerArr, err = controller.repository.GetEtcdWorkers(); err != nil {
		return c.JSON(http.StatusOK, responses.Response(code.QueryError, "失败", err.Error()))
	} else {
		return c.JSON(http.StatusOK, responses.Response(200, "成功", workerArr))
	}
}
